<template>
  <el-dialog
    :title="'上传课件'"
    :visible.sync="uploadForm.visible"
    width="500px"
  >
    <div class="el-scroll-box">
      <el-scrollbar ref="wrapperScroll">
        <el-form ref="uploadForm" :model="uploadForm" label-width="60px" style="padding-right:10px">
          <el-form-item label="文件：">
            <el-upload
              ref="upload"
              :multiple="true"
              :accept="uploadForm.accept"
              style="width:100%"
              class="upload-demo"
              :limit="uploadForm.limit"
              action="#"
              :file-list="uploadForm.fileList"
              :auto-upload="false"
              :on-change="uploadForm.fileChange"
              :on-remove="uploadForm.fileRemove"
              :on-exceed="uploadForm.fileExceed"
              :show-file-list="false"
            >
              <!-- <div slot="tip" class="el-upload__tip">{{ uploadForm.tip }}</div> -->
              <div>提示：{{ uploadForm.tip }}</div>
              <el-button slot="trigger" size="mini" type="primary">选取文件</el-button>
              <div v-for="item in uploadForm.fileList" :key="item.uid" class="file-item">
                <svg-icon class="wenbenmoban" icon-class="icon-wenbenmoban" />
                <div class="file-info">
                  <p v-if="!item.cEditName">
                    <span>{{ item.fileName }}</span>
                    <el-button type="text" @click="editFileName(item, true)">重命名</el-button>
                  </p>
                  <p v-else>
                    <el-input v-model="item.fileName" clearable="" style="width:270px" />
                    <el-button type="text" @click="editFileName(item, false)">确定</el-button>
                  </p>
                </div>
                <i class="el-icon-close" @click="uploadForm.fileRemove(item)" />
              </div>

              <!-- <div slot="file" slot-scope="{file}" class="file-item">
                <svg-icon class="wenbenmoban" icon-class="icon-wenbenmoban" />
                <div class="file-info">
                  <p v-if="!file.cEditName">
                    <span>{{ file.fileName }}</span>
                    <el-button type="text" @click="editFileName(file, true)">重命名</el-button>
                  </p>
                  <p v-else>
                    <el-input v-model="file.fileName" clearable="" style="width:270px" />
                    <el-button type="text" @click="editFileName(file, false)">确定</el-button>
                  </p>
                </div>
                <i class="el-icon-close" @click="uploadForm.fileRemove(file)" />
              </div> -->
            </el-upload>
          </el-form-item>
        </el-form>
      </el-scrollbar>
    </div>
    <!-- 上传进度条 -->
    <el-progress
      v-if="params.percentage"
      style="margin-top:10px"
      :percentage="params.percentage"
    />
    <dialog-btn slot="footer" />
  </el-dialog>
</template>

<script>
let that
export default {
  name: 'Upload',
  props: {
    params: {
      type: Object,
      default: () => {
        return {
          visible: false,
          accept: 'video/*', // 上传类型
          tip: '只能上传视频文件！', // 文字提示
          limit: 2, // 限制上传数量
          name: '', // 上传文件重命名 // 暂未用到
          fileList: [], // 上传文件列表
          fileChange: () => {}, // 文件列表修改函数
          fileExceed: () => {}, // 文件列表超过限制提示
          fileRemove: () => {} // 文件列表移除函数
        }
      }
    }
  },
  data() {
    return {
      uploadForm: {
        accept: 'video/*', // 上传类型
        tip: '请上传视频文件！', // 文字提示
        limit: 100, // 限制上传数量
        name: '', // 上传文件重命名 // 暂未用到
        fileList: [], // 上传文件列表
        fileChange: (file, fileList) => that.fileChange(file, fileList),
        fileExceed: () => that.fileExceed(),
        fileRemove: (file) => that.fileRemove(file)
      }
    }
  },
  created() {
    that = this
    // 如果外部有传入使用外部的params
    that.uploadForm = { ...that.uploadForm, ...that.params }
  },
  methods: {
    // 重命名文件名
    fileRename(_file, name) {
      return new Promise((res, rej) => {
        const suffix = _file.name.substring(_file.name.lastIndexOf('.')) // 获取文件名后缀
        const file = new File([_file], name + suffix, {
          type: _file.type
        })
        res(file)
      })
    },
    // 查询上传文件是否同名
    checkFileSameName(file) {
      let fileNames = that.uploadForm.fileLists.map(item => item.name)
      fileNames = [...that.uploadForm.fileList.map(file => file.fileName), ...fileNames]
      if (fileNames.includes(file.fileName) || fileNames.includes(file.name)) {
        that.$refs.upload.handleRemove(file)
        return true
      }
      return false
    },
    // 获取文件名
    getFileName(name) {
      return name.substring(0, name.lastIndexOf('.'))
    },
    // 文件列表改变
    fileChange(file) {
      that.$set(file, 'cEditName', false) // 先不能编辑文件名
      that.$set(file, 'fileName', that.getFileName(file.name)) // 文件名
      // 查询文件是否同名
      if (that.checkFileSameName(file)) {
        return that.$message.warning('上传文件重名，请重新选择文件或修改文件名再次上传！')
      }
      that.uploadForm.fileList.push(file)
    },
    // 超出最大上传限制
    fileExceed() {
      that.$message.warning(`当前限制选择 ${that.uploadForm.limit} 个文件！`)
    },
    // 文件列表删除
    fileRemove(file) {
      that.uploadForm.fileList = that.uploadForm.fileList.filter(item => item.uid !== file.uid)
    },
    // 编辑文件名称
    async editFileName(file, bool) {
      if (!file.fileName) return that.$message.warning('文件名不能为空')
      if (!bool) {
        // 查询文件同名
        if (this.checkFileListSameName(file)) {
          return that.$message.warning('上传文件重名，请重新选择文件或修改文件名再次上传！')
        }
      }
      that.$set(file, 'cEditName', bool)
    },
    // 查询文件同名
    checkFileListSameName(file) {
      // console.log('file')
      // console.log(file)
      // 1.判断是否重名
      let fileNames = that.uploadForm.fileLists.map(item => item.name)
      const uploadFormFiles = []
      that.uploadForm.fileList.forEach(item => {
        if (item.uid !== file.uid) {
          uploadFormFiles.push(item)
        }
      })
      fileNames = [...uploadFormFiles.map(file => file.fileName), ...fileNames]
      let prefixName = file.name.substring(file.name.lastIndexOf('.')) // 获取文件名后缀
      prefixName = file.fileName + prefixName
      if (fileNames.includes(prefixName)) {
        return true // this.$message.warning('文件名称重复')
      }
      return false
    },
    // 点击上传
    async confirm() {
      const fileList = that.uploadForm.fileList
      if (!fileList.length) return
      // console.log('fileList')
      // console.log(fileList)
      const newFileList = []
      for (let i = 0; i < fileList.length; i++) {
        const file = fileList[i]
        if (!file.fileName) {
          return that.$message.warning('文件名不能为空')
        }
        // 查询文件同名
        if (this.checkFileListSameName(file)) {
          return that.$message.warning('上传文件重名，请重新选择文件或修改文件名再次上传！')
        }
        // 修改文件名
        const newFlie = await that.fileRename(file.raw, file.fileName)
        newFileList.push(newFlie)
      }
      // console.log('newFileList')
      // console.log(newFileList)

      that.uploadForm.confirm(newFileList)
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-scrollbar__wrap {
  overflow-x: hidden;
}
.el-scroll-box {
  width: 100%;
  height: 400px;
  .el-scrollbar {
    height:100%
  }
}
.file-li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid #eee;
  color: #606266;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color .3s;
  white-space: nowrap;
  i {
    font-size: 16px;
    cursor: pointer;
  }
}
.file-item {
  position: relative;
  overflow: hidden;
  border: 1px solid #c0ccda;
  border-radius: 6px;
  box-sizing: border-box;
  padding: 10px;
  height: 92px;
  display: flex;
  align-items: center;
  margin-bottom: 5px;
  .file-info {
    flex-grow: 1;
    p {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
    }
  }
  .wenbenmoban {
    font-size: 50px;
    margin-right: 10px;
  }
  i {
    position: absolute;
    top: 5px;
    right: 5px;
    cursor: pointer;
    opacity: .75;
    color: #606266;
  }
}
</style>
